package com.djf.service;

import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.delegate.JavaDelegate;
import org.springframework.stereotype.Service;

/**
 * 通知服务类
 * 实现Flowable的JavaDelegate接口，用于处理流程中的服务任务
 * 
 * @author djf
 * @date 2025/01/20
 */
@Slf4j
@Service
public class NotificationService implements JavaDelegate {

    @Override
    public void execute(DelegateExecution execution) {
        String activityId = execution.getCurrentActivityId();
        String processInstanceId = execution.getProcessInstanceId();
        String businessKey = execution.getProcessInstanceBusinessKey();
        
        log.info("执行通知服务，流程实例ID: {}, 业务Key: {}, 活动ID: {}", 
                processInstanceId, businessKey, activityId);
        
        try {
            if ("approvalNotification".equals(activityId)) {
                sendApprovalNotification(execution);
            } else if ("rejectionNotification".equals(activityId)) {
                sendRejectionNotification(execution);
            }
        } catch (Exception e) {
            log.error("通知发送失败: {}", e.getMessage(), e);
            throw new RuntimeException("通知发送失败: " + e.getMessage());
        }
    }

    /**
     * 发送审批通过通知
     * 
     * @param execution 执行上下文
     */
    private void sendApprovalNotification(DelegateExecution execution) {
        String startUserId = (String) execution.getVariable("startUserId");
        String leaveType = (String) execution.getVariable("leaveType");
        Object leaveDays = execution.getVariable("leaveDays");
        String startDate = (String) execution.getVariable("startDate");
        String endDate = (String) execution.getVariable("endDate");
        
        log.info("发送审批通过通知给用户: {}", startUserId);
        log.info("请假信息 - 类型: {}, 天数: {}, 开始日期: {}, 结束日期: {}", 
                leaveType, leaveDays, startDate, endDate);
        
        // 这里可以集成邮件服务、短信服务、企业微信等
        sendEmail(startUserId, "请假申请审批通过", buildApprovalMessage(leaveType, leaveDays, startDate, endDate));
        sendSMS(startUserId, "您的请假申请已审批通过，请假期间请注意安全。");
        
        // 更新流程变量
        execution.setVariable("notificationSent", true);
        execution.setVariable("notificationType", "approval");
    }

    /**
     * 发送审批拒绝通知
     * 
     * @param execution 执行上下文
     */
    private void sendRejectionNotification(DelegateExecution execution) {
        String startUserId = (String) execution.getVariable("startUserId");
        String leaveType = (String) execution.getVariable("leaveType");
        String managerComment = (String) execution.getVariable("managerComment");
        String hrComment = (String) execution.getVariable("hrComment");
        
        log.info("发送审批拒绝通知给用户: {}", startUserId);
        
        String rejectReason = buildRejectReason(managerComment, hrComment);
        
        // 发送通知
        sendEmail(startUserId, "请假申请审批拒绝", buildRejectionMessage(leaveType, rejectReason));
        sendSMS(startUserId, "您的请假申请未通过审批，请查看详细原因。");
        
        // 更新流程变量
        execution.setVariable("notificationSent", true);
        execution.setVariable("notificationType", "rejection");
    }

    /**
     * 发送邮件通知
     * 
     * @param userId 用户ID
     * @param subject 邮件主题
     * @param content 邮件内容
     */
    private void sendEmail(String userId, String subject, String content) {
        // 这里应该集成实际的邮件服务
        log.info("发送邮件给用户 {}: 主题={}, 内容={}", userId, subject, content);
        
        // 示例：可以集成Spring Mail或者第三方邮件服务
        // mailService.sendMail(getUserEmail(userId), subject, content);
    }

    /**
     * 发送短信通知
     * 
     * @param userId 用户ID
     * @param message 短信内容
     */
    private void sendSMS(String userId, String message) {
        // 这里应该集成实际的短信服务
        log.info("发送短信给用户 {}: {}", userId, message);
        
        // 示例：可以集成阿里云短信、腾讯云短信等
        // smsService.sendSMS(getUserPhone(userId), message);
    }

    /**
     * 构建审批通过消息
     * 
     * @param leaveType 请假类型
     * @param leaveDays 请假天数
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return 消息内容
     */
    private String buildApprovalMessage(String leaveType, Object leaveDays, String startDate, String endDate) {
        StringBuilder message = new StringBuilder();
        message.append("您好！\n\n");
        message.append("您的请假申请已审批通过，详情如下：\n");
        message.append("请假类型：").append(getLeaveTypeName(leaveType)).append("\n");
        message.append("请假天数：").append(leaveDays).append("天\n");
        message.append("开始日期：").append(startDate).append("\n");
        message.append("结束日期：").append(endDate).append("\n\n");
        message.append("请假期间请注意安全，如有紧急情况请及时联系公司。\n\n");
        message.append("祝您生活愉快！\n");
        message.append("人力资源部");
        return message.toString();
    }

    /**
     * 构建审批拒绝消息
     * 
     * @param leaveType 请假类型
     * @param rejectReason 拒绝原因
     * @return 消息内容
     */
    private String buildRejectionMessage(String leaveType, String rejectReason) {
        StringBuilder message = new StringBuilder();
        message.append("您好！\n\n");
        message.append("很抱歉，您的").append(getLeaveTypeName(leaveType)).append("申请未通过审批。\n\n");
        message.append("拒绝原因：\n").append(rejectReason).append("\n\n");
        message.append("如有疑问，请联系您的直属领导或人力资源部。\n\n");
        message.append("人力资源部");
        return message.toString();
    }

    /**
     * 构建拒绝原因
     * 
     * @param managerComment 领导意见
     * @param hrComment HR意见
     * @return 拒绝原因
     */
    private String buildRejectReason(String managerComment, String hrComment) {
        StringBuilder reason = new StringBuilder();
        if (managerComment != null && !managerComment.trim().isEmpty()) {
            reason.append("直属领导意见：").append(managerComment).append("\n");
        }
        if (hrComment != null && !hrComment.trim().isEmpty()) {
            reason.append("HR部门意见：").append(hrComment).append("\n");
        }
        return reason.length() > 0 ? reason.toString() : "未提供具体原因";
    }

    /**
     * 获取请假类型名称
     * 
     * @param leaveType 请假类型代码
     * @return 请假类型名称
     */
    private String getLeaveTypeName(String leaveType) {
        switch (leaveType) {
            case "annual":
                return "年假";
            case "sick":
                return "病假";
            case "personal":
                return "事假";
            case "maternity":
                return "产假";
            default:
                return "请假";
        }
    }
}